package com.sophossystems.client.asmon.dao.spring;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.transaction.annotation.Transactional;

import com.sophossystems.client.asmon.dao.RoleDao;
import com.sophossystems.client.asmon.dto.RoleDTO;
import com.sophossystems.client.asmon.dto.RolePkDTO;
import com.sophossystems.client.asmon.exceptions.DaoException;
import com.sophossystems.client.asmon.hibernate.Role;

public class RoleDaoImpl extends AbstractDAO implements RoleDao
{
	
	private static Logger log = Logger
			.getLogger(RoleDaoImpl.class);
	
	/**
	 * Method 'insert'
	 * 
	 * @param dto
	 * @return ActivityPk
	 */
	
	@Override
	@Transactional
	public RolePkDTO insert(final RoleDTO dto){
		RolePkDTO exito =null ;
	try {
		 exito = (RolePkDTO) getHibernateTemplate().execute(new HibernateCallback() {
			/**
			 * {@inheritDoc}
			 * 
			 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
			 */
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
			    Transaction tx = session.beginTransaction();
			    RolePkDTO  pk = null;
			    Role rol = new Role();
			    rol.mapper(dto);
			    session.save(rol);
			    log.debug("El insert de roles: "+dto.getName() +" Superior: "+dto.getIdRoleSuperior());
			    System.out.println("El insert de roles: "+dto.getName() +" Superior: "+dto.getIdRoleSuperior());		
				tx.commit();
				try{
				RoleDTO res = findWhereNameEquals(dto.getName()).get(0);
				 pk = new RolePkDTO ();
				pk.setIdRole(res.getIdRole());
				}
				catch(DaoException es)
				{
					throw new HibernateException("Insersion: " +es.getMessage());
				}
				return pk;
			
				
			}

			
		});
	///	 return exito;
	} catch (final Exception e) {
		logger.error("Error: getActivity, cause: " + e.getMessage(), e);
		
	}
	return exito;
}

		
	/** 
	 * Updates a single row in the Activity table.
	 */
	
	@Override
	@Transactional
	public void update(final RoleDTO dto) throws DaoException
	{
		
			 getHibernateTemplate().execute(
					new HibernateCallback() {
						/**
						 * {@inheritDoc}
						 * 
						 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
						 */
						@Override
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							RolePkDTO pk = null;
							RoleDTO res = null;
							Transaction tx = session.beginTransaction();
							// Aqui primero se busca si existe el registro
							try {
								res = findByPrimaryKey(dto
										.getIdRole());
								pk = new RolePkDTO();
								pk.setIdRole(res.getIdRole());
							} catch (DaoException es) {
								throw new HibernateException(
										"Update RoleDao: "
												+ es.getMessage());
							}
							///aqui se actualizar los campos y con los de la entrada  
							//cuidado de actualiza todo.
							Role persis = new Role();
							persis.mapper(dto);
							persis.setIdRole(res.getIdRole());
							session.update(persis);
							tx.commit();
							return null;
						}

					});
	
	}

	/** 
	 * Deletes a single row in the Activity table.
	 */
	
	@Override
	@Transactional
	public void delete(final RolePkDTO pk) throws DaoException
	{
		
		
		try {
			 getHibernateTemplate().execute(new HibernateCallback() {
				/**
				 * {@inheritDoc}
				 * 
				 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
				 */
				@Override
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
				    Transaction tx = session.beginTransaction();
				    Role role = (Role)session.load(Role.class,pk.getIdRole());
				    session.delete(role);
					tx.commit();
					return null;
				}		
			});
		} catch (final Exception e) {
			logger.error("Error: getRole, cause: " + e.getMessage(), e);
			throw new DaoException("Error: getActivity, cause: " + e.getMessage());
		}
	}

	
	/**
	 * Method 'getTableName'
	 * 
	 * @return String
	 */
	public String getTableName()
	{
		return "Role";
	}

	/** 
	 * Returns all rows from the Role table that match the criteria 'idRole = :idRole'.
	 */
	@Override
	@Transactional
	public RoleDTO findByPrimaryKey(final int idRole)
			throws DaoException	{
		RoleDTO role = null;
		try {
			role = (RoleDTO) getHibernateTemplate().execute(
					new HibernateCallback() {
						/**
						 * {@inheritDoc}
						 * 
						 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
						 */
						@Override
						@SuppressWarnings("unchecked")
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							logger.debug("Entradno a findByPrimaryKey con id: "+idRole);
							RoleDTO role = null;
							String query = "SELECT r.idRole as idRole, r.name as name, r.idRoleSuperior as idRoleSuperior FROM "
							+ getTableName() + " r WHERE r.idRole = :role";
							List<RoleDTO> lista = session
									.createQuery(query)
									.setInteger("role", idRole)
									.setResultTransformer(
											Transformers
													.aliasToBean(RoleDTO.class))
									.list();
							
							if (lista != null && lista.size() > 0) {
								role = lista.get(0);
								logger.debug("RoleDaoImpl - se encontro un role" +role.getName());
							} else {
								logger.debug("RoleDaoImpl - se encontro un la lista devolvio null");
							}
							
							return role;
						}
					});

		}
		
		catch (Exception e) {
			logger.error("Error: RoleDTO.findByPrimaryKey, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return role;
	}

	/** 
	 * Returns all rows from the Role table that match the criteria ''.
	 */
	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<RoleDTO> findAll() 
			throws DaoException {
		List<RoleDTO> role = null;
		try {
			role = (List<RoleDTO>)getHibernateTemplate().execute(
					new HibernateCallback() {
						
						@Override
						public Object doInHibernate(Session session) throws HibernateException,
								SQLException {
							
							Query oQuery = session.createQuery("SELECT  r.idRole as idRole FROM " + getTableName()+" r" );
							List<RoleDTO> lista = oQuery
									.setResultTransformer(Transformers
											.aliasToBean(RoleDTO.class)).list();
							return lista;
						}
					});
		}
		catch (Exception e) {
			logger.error("Error: Role, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return role;
	}

	/** 
	 * Returns all rows from the Role table that match the criteria 'idRole = :idRole'.
	 */
	@Transactional
	public List<RoleDTO> findWhereIdRoleEquals(final int idRole) 
			throws DaoException	{
		
		List<RoleDTO> lista = new ArrayList<RoleDTO>();

		RoleDTO role = this.findByPrimaryKey(idRole);
		lista.add(role);
		return lista;
		
	}

	/** 
	 * Returns all rows from the Role table that match the criteria 'Name = :name'.
	 */
	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<RoleDTO> findWhereNameEquals(final String name)
			throws DaoException	{
		List<RoleDTO> role = null;
		try {
			role = (List<RoleDTO>)getHibernateTemplate().execute(
					new HibernateCallback() {
						
						@Override
						public Object doInHibernate(Session session) throws HibernateException,
								SQLException {

							Query oQuery = session.createQuery("SELECT r.idRole as idRole, r.name as name," +
									" r.idRoleSuperior as idRoleSuperior FROM " + getTableName() + 
									" r WHERE r.name = :name");
							oQuery.setString("name", name);
							List<RoleDTO> roleDto = oQuery.setResultTransformer(
									Transformers.aliasToBean(RoleDTO.class)).list();
							return roleDto;
						}
					});
//			
		}
		catch (Exception e) {
			logger.error("Error: Role, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return role;
	}

	@Override
	public RolePkDTO findLastInsert() throws DaoException {
		RolePkDTO direccion = null;
		try {
			direccion = (RolePkDTO) getHibernateTemplate().execute(
					new HibernateCallback() {

						@Override
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							
							Query oQuery = session
									.createQuery("SELECT max(r.idRole) as idRole FROM "
											+ getTableName()
											+ " r ");
							
							RolePkDTO direccionDto = (RolePkDTO) oQuery
									.setResultTransformer(Transformers
											.aliasToBean(RolePkDTO.class)).list().get(0);
							return direccionDto;
						}
					});
		
		} catch (Exception e) {
			logger.error("Error: RoleDaoImpl, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return direccion;

	}

}
